#ifndef POINTCLOUD_FUSION_H
#define POINTCLOUD_FUSION_H

#define _APP_NAME_ "pointcloud_fusion"

#include "ros/ros.h"
#include "tf/tf.h"
#include "eigen3/Eigen/Core"
#include <eigen3/Eigen/LU>
#include "sensor_msgs/PointCloud2.h"
#include "tf2_ros/buffer.h"
#include "tf2_ros/transform_listener.h"
#include "geometry_msgs/PoseStamped.h"
#include "pcl_ros/transforms.h"
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/filters/passthrough.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

class PointCloudFusion{
    public:
        PointCloudFusion();
        ~PointCloudFusion();
        void run();
    
    private:
        ros::NodeHandle nh_;
        ros::NodeHandle private_nh_;
    
    private:
        tf2_ros::Buffer buffer_;
        tf2_ros::TransformListener listener_;
    
    private:
        std::string input_lidar_topic_;
        std::string input_lidar_frame_id;
        std::string input_map_border_topic_;
        std::string input_map_border_frame_id;
        std::string output_confusion_lidar_topic_;
        std::string output_confusion_lidar_frame_id;
    
    private:
        double passthrough_x_min;
        double passthrough_x_max;
        double passthrough_y_min;
        double passthrough_y_max;
        double passthrough_z_min;
        double passthrough_z_max;

        double map_border_passthrough_x_min;
        double map_border_passthrough_x_max;
        double map_border_passthrough_y_min;
        double map_border_passthrough_y_max;
    
    private:
        sensor_msgs::PointCloud2 lidar_pc_trans;
        sensor_msgs::PointCloud2 map_border_pc_trans;

    private:
        ros::Subscriber lidar_sub_;
        ros::Subscriber map_border_sub_;
        ros::Publisher confusion_lidar_pub_;
    
    private:
        void lidar_call_back(const sensor_msgs::PointCloud2::ConstPtr& msg);
        void map_border_call_back(const sensor_msgs::PointCloud2::ConstPtr& msg);
        void process(const ros::TimerEvent& e);
};

#endif